#include "glwidget.h"


DecodeThread::DecodeThread(GLWidget* screen, Video* v) :
    QThread(screen), v(v)
{
}

void DecodeThread::run() {
    static struct SwsContext* swsContext = sws_getContext(v->vCodecCtx->width, v->vCodecCtx->height, v->vCodecCtx->pix_fmt, v->vCodecCtx->width, v->vCodecCtx->height, PIX_FMT_RGBA, SWS_BICUBIC, NULL, NULL, NULL);
    int frameFinished = 0;
    AVPacket packet;

    AVFrame* sFrame = avcodec_alloc_frame();
    AVFrame* dFrame;
    while (true) {
        if (v->state == STOPPED)
            break;
        else if (v->state == PAUSED
                 || v->state == SEEKING
                 || v->pQueue->size >= PictureQueue::MAX_PICTURE_QUEUE_SIZE
                 /*|| v->seekFlag*/) {
            sleep(0.02);
            continue;
        }
        else if (v->state == PLAY || STOPPING) {
            if (v->vPacketQueue->size > 0)
                 v->vPacketQueue->pop(&packet);
            else {
                if (v->state == PLAY) {
                    sleep(0.02);
                    continue;
                }
                else if (v->state == STOPPING) {
                    break;
                }
            }

            dFrame = avcodec_alloc_frame();
            avpicture_alloc((AVPicture*)dFrame, PIX_FMT_RGBA, v->vCodecCtx->width, v->vCodecCtx->height);
            if (avcodec_decode_video2(v->vCodecCtx, sFrame, &frameFinished, &packet) <= 0 )
                std::cout << "Nooo...." << std::endl;

            //free packet if it has neither dts nor pts
            if (packet.pts == AV_NOPTS_VALUE && packet.dts == AV_NOPTS_VALUE) {
                av_free_packet(&packet);
                //av_free(sFrame);
                av_free(dFrame);
                continue;
            }

            if(frameFinished) {
                sws_scale(swsContext, sFrame->data, sFrame->linesize, 0, v->vCodecCtx->height, dFrame->data, dFrame->linesize);

                v->pQueue->mutex->lock();
                double tb = av_q2d(v->formatCtx->streams[v->videoIndex]->time_base);
                v->pQueue->push(dFrame, packet.pts == AV_NOPTS_VALUE ? packet.pts * tb : packet.dts * tb);
                v->pQueue->mutex->unlock();
            }
            else {
                av_free(dFrame);
            }

            av_free_packet(&packet);
            frameFinished = 0;
        }
    }

    std::cout << "decode thread finished" << std::endl;
}
